package com.doeis.uwork.dao;

import java.util.ArrayList;
import java.util.List;

import com.doeis.common.utils.StringUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.WriteResult;
import com.mongodb.util.JSON;
import com.voland.core.annotation.Table;
import com.voland.core.db.MongoManage;
import com.voland.core.db.Page;

public class MongoDao {
	
	public <T> List<DBObject> query(String dbname, Class<T> beanClass, DBObject query, DBObject sort) throws Exception {
		DBCollection coll = getCollection(dbname, beanClass);
		DBCursor cur;
		if (query != null) {
			cur = coll.find(query);
		} else {
			cur = coll.find();
		}
		
		if (sort != null) {
			cur.sort(sort);
		}
		
		List<DBObject> list = null;
		if (cur != null) {
			list = (List<DBObject>) cur.toArray();
		}else{
			list = new ArrayList<DBObject>();
		}
		return list;
		
	}
	
	public <T> Page<T> querySlice(String dbname, Class<T> beanClass, Page<T> page) throws Exception {
		return querySlice(dbname, beanClass, page, null, null);
	}

	public <T> Page<T> querySlice(String dbname, Class<T> beanClass, Page<T> page, DBObject query,
			DBObject sort) throws Exception {
		DBCollection coll = getCollection(dbname, beanClass);
		DBCursor cur;
		if (query != null) {
			cur = coll.find(query);
		} else {
			cur = coll.find();
		}
		//求总记录数
		int total = cur.size();
		page.setTotalRecords(total);
		
		if (sort != null) {
			cur.sort(sort);
		}
		
		Integer start = page.getPer()*(page.getPage()-1);
		Integer limit = page.getPer();
		if(start != null){
			if (start.intValue() == 0) {
				cur.limit(limit);
			} else {
				if(limit != null){
					cur.skip(start).limit(limit);
				}else{
					cur.skip(start);
				}
			}
		}
		cursor2list(cur,page);
		return page;
	}
	
	public <T> DBObject readByCondition(String dbname, Class<T> beanClass, DBObject query) throws Exception {
		DBCollection coll = getCollection(dbname, beanClass);
		DBObject r = coll.findOne(query);
		return r;
	}
	
	public <T> DBObject readById(String dbname, Class<T> beanClass, String id) throws Exception {
		DBCollection coll = getCollection(dbname, beanClass);		
		BasicDBObject ref=new BasicDBObject();
		ref.put("_id", id);
		DBObject r = coll.findOne(ref);
		return r;
	}
	
	
	public <T> void update(String dbname, Class<T> beanClass, DBObject query,  DBObject obj) throws Exception{
		DBCollection coll = getCollection(dbname, beanClass);
		coll.update(query, obj);
	}

	
	public <T> void update(String dbname, Class<T> beanClass, DBObject obj) throws Exception{
		BasicDBObject query=new BasicDBObject();
		query.put("_id", obj.get("_id"));		
		update(dbname, beanClass, query, obj);
	}


	public <T> WriteResult insert(String dbname, Class<T> beanClass, DBObject ...arr) throws Exception {
		DBCollection coll = getCollection(dbname, beanClass);
		return coll.insert(arr);		
	}
	
	public <T> WriteResult insert(String dbname, Class<T> beanClass, List<DBObject> list) throws Exception {
		DBCollection coll = getCollection(dbname, beanClass);
		
		return coll.insert(list);		
	}
	
	public <T> DBCollection getCollection(String dbname, Class<T> c) throws Exception{
		DB db = MongoManage.getMongoDB(dbname);
		String table = getTableName(c);
		if(StringUtils.isBlank(table)){
			return null;
		}
		
		return  db.getCollection(table);		
	}
	
	private <T> void cursor2list( DBCursor cur, Page<T> page) {
		List<T> list = null;
		if (cur != null) {
			list = (List<T>) cur.toArray();
		}else{
			list = new ArrayList<T>();
		}
		page.setResults(list);
	}
	
	private <T> String getTableName(Class<T> c ){
		if(c.isAnnotationPresent(Table.class)){
			Table e = (Table)c.getAnnotation(Table.class);
			return e.name(); 
		}
		return null;
	}
	
	//分组查询
	/** 
	    * keyColumn : new String[]{"xxxName","xxxType"} <br> 
	    * condition : 查询条件 ，可为空<br> 
	    * initial : 分组统计初始变量，为空时自动为每列提供初始变量<br> 
	    * reduce ： 记录处理function<br> 
	    * finalize : finalize函数，可为空 <br> 
	 * @throws Exception 
	    */
	    public <T> BasicDBList group(String dbname, Class<T> beanClass,
	    		String[] keyColumn, DBObject condition, 
	            DBObject initial, String reduce, String finalize) throws Exception { 
	    	
	        DBCollection coll = getCollection(dbname,beanClass); 
	        DBObject key = new BasicDBObject(); 
	        for (int i = 0; i < keyColumn.length; i++) { 
	            key.put(keyColumn[i], true); 
	        } 
	        condition = (condition == null) ? new BasicDBObject() : condition; 
	        if (StringUtils.isBlank(finalize)) { 
	            finalize = null; 
	        } 
	        if (initial == null) {      //定义一些初始变量 
	            initial = new BasicDBObject(); 
	            for (int i = 0; i < keyColumn.length; i++) { 
	                DBObject index = new BasicDBObject(); 
	                index.put("count", 0); 
	                index.put("sum", 0); 
	                index.put("max", 0); 
	                index.put("min", 0); 
	                index.put("avg", 0); 
	                index.put("self", ""); 
	                initial.put(keyColumn[i], index); 
	            } 
	        } 
	        BasicDBList resultList = (BasicDBList) coll.group(key, condition, 
	                initial, reduce, finalize); 
//	        		DBObject key,   --分组字段，即group by的字段
//	                DBObject cond,        --查询中where条件
//	                DBObject initial,     --初始化各字段的值
//	                String reduce,        --每个分组都需要执行的Function
//	                String finial         --终结Funciton对结果进行最终的处理
	        return resultList; 
	    }

}
